/*
 * @ProblemId: 
 * @Probtitle: 
 * @Location: 
 * @Author: Morales
 * @Date: 2020-12-11 09:20:20
 * @LastEditTime: 2020-12-13 11:09:05
 * @Space: https://space.bilibili.com/350869102
 * @E-mail: lovexposed@foxmail.com
 * @Blog: https://blog.csdn.net/baidu_41248654
 * @Powered by: Havoc_Wei
 */
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef int VerTexType;
#define MVNum 100

typedef struct{
    int *top;
    int *base;
    int StackSize;
}SqStack;

typedef struct ArcNode{ // 边结点
    int adjvex; // 该边所指向的顶点的位置
    struct ArcNode *nextarc; // 指向下一条边的指针
    // OtheInfo info;
}ArcNode;
typedef struct VNode{ // 顶点信息
    VerTexType data;
    VerTexType inDegree=0, outDegree=0;
    ArcNode *firstarc; // 指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum];
typedef struct{
    AdjList vertices;
    int vexnum, arcnum; // 图的当前顶点数和边数
}ALGraph;

bool isEmpty(SqStack S)
{
    if(S.top == S.base) return 1;
    else return 0;
}
void InitStack(SqStack &S)
{
    S.base = new int[MVNum];
    if(!S.base) exit(-2); // OVERFLOW
    S.top = S.base;
    S.StackSize = MVNum;
}
void Push(SqStack &S, int Elem)
{
    if(S.top-S.base == S.StackSize) exit(0);
    *S.top++ = Elem;
}
int Pop(SqStack &S)
{
    if(isEmpty(S)) exit(0);
    return *--S.top;
}

int LocateVex(ALGraph G, VerTexType v)
{
    for(int i=0; i<G.vexnum; i++)
        if(G.vertices[i].data == v) return i;
    return -1;
}
void CreateDG(ALGraph &G)
{ // 创建有向图
    cin>>G.vexnum>>G.arcnum;
    for(int i=0; i<G.vexnum; i++)
    {
        cin>>G.vertices[i].data;
        G.vertices[i].firstarc = NULL;
    }
    for(int k=0; k<G.arcnum; k++)
    {
        int v1, v2;
        cin>>v1>>v2;
        int i=LocateVex(G, v1), j=LocateVex(G, v2);
        // 确定v1和v2在G中位置，即顶点在G.vertices中的序号
        G.vertices[j].inDegree++;
        G.vertices[i].outDegree++;
        ArcNode *p=new ArcNode;
        p->adjvex = j;
        p->nextarc = G.vertices[i].firstarc;
        G.vertices[i].firstarc = p;
    }
}

int AOVSort(ALGraph G, int *topo)
{
    SqStack S;
    InitStack(S);
    for(int i=0; i<G.vexnum; i++)
        if(!G.vertices[i].inDegree) Push(S, i);
    int cnt = 0;
    while(!isEmpty(S))
    {
        int tmp = Pop(S);
        topo[cnt++] = tmp+1;
        ArcNode *p = G.vertices[tmp].firstarc;
        while(p)
        {
            //int k = LocateVex(G, p->adjvex);
            int k = p->adjvex;
            G.vertices[k].inDegree--;
            if(!G.vertices[k].inDegree) Push(S, k);
            p = p->nextarc;
        }
    }
    if(cnt<G.vexnum) return 0;
    else return 1;
}
/*
int AOVSort_withSTL(ALGraph G, int *topo)
{
    stack<int> st;
    for(int i=0; i<G.vexnum; i++)
        if(!G.vertices[i].inDegree) st.push(i);
    int cnt = 0;
    while(!st.empty())
    {
        int tmp = st.top();
        topo[cnt++] = tmp+1;
        st.pop();
        ArcNode *p = G.vertices[tmp].firstarc;
        while(p)
        {
            //int k = LocateVex(G, p->adjvex);
            int k = p->adjvex;
            G.vertices[k].inDegree--;
            if(!G.vertices[k].inDegree) st.push(k);
            p = p->nextarc;
        }
    }
    if(cnt<G.vexnum) return 0;
    else return 1;
}
*/
int main()
{
    //ios::sync_with_stdio(false);
    ALGraph G;
    int topu[MVNum];
    fill(topu, topu+MVNum, 0);
    CreateDG(G);
    if(AOVSort(G, topu))
    {
        for(int i=0; i<G.vexnum; i++)
            cout<<"v"<<topu[i]<<" ";
    }
    return 0;
}
